package com.yfqy.app.filter;

import com.yfqy.app.security.login.LoginUserInfo;
import com.yfqy.app.util.AuthUserContext;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import java.io.IOException;

@Component
public class AuthUserContextFilter implements Filter {

    private static final Logger log = LoggerFactory.getLogger(AuthUserContextFilter.class);

    // 需要排除的URL路径（可选）
    private static final String[] EXCLUDE_PATHS = {
            "/api/client/auth/login",
            "/api/client/auth/register",
            "/api/client/public/",
            "/actuator/",
            "/swagger-ui/",
            "/v3/api-docs"
    };

    @Override
    public void doFilter(ServletRequest servletRequest,
                         ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) servletRequest;

        // 先判断是否需要处理该请求
        if (!shouldProcessRequest(request)) {
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }

        // 初始化ThreadLocal为null
        AuthUserContext.setLocalAuthUser(null);

        try {
            // 获取认证信息
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

            // 检查认证是否有效
            if (isValidAuthentication(authentication)) {
                Object principal = authentication.getPrincipal();

                // 安全地转换用户信息
                LoginUserInfo loginUserInfo = extractLoginUserInfo(principal);
                if (loginUserInfo != null) {
                    AuthUserContext.setLocalAuthUser(loginUserInfo);
                    log.debug("设置用户上下文: userId={}, username={}", loginUserInfo.getId(), loginUserInfo.getNickname());
                }
            }

            // 继续执行过滤器链
            filterChain.doFilter(servletRequest, servletResponse);

        } finally {
            // 确保在请求完成后清理ThreadLocal
            AuthUserContext.clearLocalAuthUser();
            log.debug("清理用户上下文");
        }
    }

    /**
     * 判断是否需要处理该请求
     */
    private boolean shouldProcessRequest(HttpServletRequest request) {
        String requestUri = request.getRequestURI();

        // 只处理内部API
        if (requestUri.startsWith("/api/internal") || requestUri.startsWith("/api/client")) {
            return true;
        }

        // 排除特定路径
        for (String excludePath : EXCLUDE_PATHS) {
            if (requestUri.startsWith(excludePath)) {
                return false;
            }
        }

        return true;
    }

    /**
     * 检查认证是否有效
     */
    private boolean isValidAuthentication(Authentication authentication) {
        return authentication != null &&
                authentication.isAuthenticated() &&
                authentication.getPrincipal() != null;
    }

    /**
     * 安全提取用户信息
     */
    private LoginUserInfo extractLoginUserInfo(Object principal) {
        if (principal instanceof LoginUserInfo) {
            return (LoginUserInfo) principal;
        }

        // 如果是其他类型的principal（如String类型的username），可以在这里处理
        log.warn("Principal类型不匹配: {}", principal.getClass().getName());
        return null;
    }
}